package io.gitee.yaoshanli.engine.service.impl;

import io.gitee.yaoshanli.engine.db.JwDbHelper;
import io.gitee.yaoshanli.engine.domain.UserModel;
import io.gitee.yaoshanli.engine.model.WfNodeModel;
import io.gitee.yaoshanli.engine.model.WfProcessModel;
import io.gitee.yaoshanli.engine.model.WfTaskHandlerModel;
import io.gitee.yaoshanli.engine.model.WfTaskModel;
import io.gitee.yaoshanli.engine.service.ITaskService;
import io.gitee.yaoshanli.engine.utils.DateUtils;
import io.gitee.yaoshanli.engine.utils.StringUtils;

import java.util.ArrayList;
import java.util.List;


public class TaskService implements ITaskService {

    TaskHandlerService taskHandlerService=new TaskHandlerService();
    CodeService codeService=new CodeService();
    FlowService flowService=new FlowService();
    ProcessService processService=new ProcessService();
    NodeService nodeService=new NodeService();

    /**
     *  获取当前任务
     * @param id
     * @return
     */
    @Override
    public WfTaskModel getTask(String id)
    {
        String sql="select * from jw_wf_task where id=?";
        Object[] args = new Object[]{id};
        return JwDbHelper.queryFirst(WfTaskModel.class,sql,args);
    }

    /**
     *  开始流程
     * @param taskId    任务ID
     * @param wfId   工作流ID
     * @param oper  操作人
     * @param name  任务名称
     * @param desc   任务描述
     * @param dept  发起部门
     * @return
     */
    @Override
    public WfTaskModel startTask(String taskId, String wfId, String oper,String name,String desc,String dept) {

        String sql="";
        Object[] args=null;
        WfNodeModel wfNodeModel=flowService.getFirstNode(wfId);
        //获取流程的第一个节点
        String node_id=wfNodeModel.getId();
        //获取流程下一步节点
        WfNodeModel wfNodeModelNext=flowService.getNextNode(wfId,node_id);
        String next_node=wfNodeModelNext.getId();
        if(getTask(taskId)==null)
        {
            //新建流程
            sql="insert into jw_wf_task (id,wf_id,task_name,task_desc,node_id,create_by,create_time,create_dept,status,update_by,update_time)" +
                    " values (?,?,?,?,?,?,?,?,?,?,?) ";
            args = new Object[]{taskId,wfId,name,desc,next_node,oper, DateUtils.getNowDate(),dept,1,oper, DateUtils.getNowDate()};
        }
        else
        {
            //发回开始之后，重新提交流程
            sql="update jw_wf_task set update_by=?,update_time=?,node_id=? where id=?" ;
            args = new Object[]{oper, DateUtils.getNowDate(),next_node,taskId};
        }

        if(JwDbHelper.update(sql,args)>0)
        {
            //执行开始节点的流程详情
            String node_name=wfNodeModel.getName();
            processService.saveProcess(wfId,taskId,node_id,node_name,oper);

            //当前流程的下一步节点的处理人员范围；  getUser();
            String group = wfNodeModelNext.getBy_group();
            changeUsersNode(wfNodeModelNext,wfId,taskId,oper);

            //查询当前的工作任务信息
            sql="select * from jw_wf_task where id=?";
            args = new Object[]{taskId};
            return JwDbHelper.queryFirst(WfTaskModel.class,sql,args);
        }
        else
        {
            return null;
        }
    }

    /**
     *  执行流程
     * @param taskId 任务ID
     * @param oper  执行人
     * @return
     */
    @Override
    public WfTaskModel executeTask(String taskId, String oper,String desc) {
        //查看当前流程的状态
        String sql="select * from jw_wf_task where id=?";
        Object[] args = new Object[]{taskId};
        WfTaskModel wfTaskModel = JwDbHelper.queryFirst(WfTaskModel.class,sql,args);
        String node_id=wfTaskModel.getNode_id();    //当前需要执行的节点
        String wf_id=wfTaskModel.getWf_id();    //当前流程ID
        //下一步节点
        WfNodeModel wfNodeModelNext=flowService.getNextNode(wf_id,node_id);
        return executeTask(taskId, wfNodeModelNext.getId(), oper, desc) ;
    }

    @Override
    public WfTaskModel executeTask(String taskId, String node_id, String oper, String desc) {
        //查看当前流程的状态
        String sql="select * from jw_wf_task where id=?";
        Object[] args = new Object[]{taskId};
        WfTaskModel wfTaskModel = JwDbHelper.queryFirst(WfTaskModel.class,sql,args);
        //String now_node_id=wfTaskModel.getNode_id();    //当前需要执行的节点
        String wf_id=wfTaskModel.getWf_id();    //当前流程ID

        //WfNodeModel wfNodeModel=flowService.getNode(wf_id,now_node_id);
        //选中的需要执行的节点
        WfNodeModel wfNodeModelNext=flowService.getNode(wf_id,node_id);

        String next_node=wfNodeModelNext.getId();
        String shape=wfNodeModelNext.getShape();
        int deal_type=wfNodeModelNext.getDeal_type();    //审批处理方式（0单人，1会签，2达到百分比）
        int deal_type_rate=wfNodeModelNext.getDeal_type_rate();  //百分比审批；计算出当前需要的审批人数
        if(shape.equals("activity"))            //执行节点
        {
            //先处理人员移除
            taskHandlerService.removeUser(wf_id,taskId,oper);
            List<WfTaskHandlerModel> list=taskHandlerService.getUserList(wf_id,taskId);
            if(deal_type==0)    //单人审批
            {
                //执行到下一个节点
                //sql="update jw_wf_task set update_by=?,update_time=?,node_id=? where id=?" ;
                //args = new Object[]{oper, DateUtils.getNowDate(),next_node,taskId};

                //重新填充下一个节点的审批人员
                changeUsersNode(wfNodeModelNext,wf_id,taskId,oper);

            }
            else if(deal_type==1)   //会签
            {
                if(list.size()>0)
                {
                    //当前会签还存在人员未审批，下一个节点还是自己
                    next_node=node_id;

                }
                else
                {
                    //下一个节点
                    changeUsersNode(wfNodeModelNext,wf_id,taskId,oper);
                }
            }
            else if(deal_type==2)   //百分比审批
            {
                //deal_type_rate，变换成需要审批的人数，如果当前人数
                int people=nodeService.getUserCount(node_id);
                people=people*(100-deal_type_rate)/100;     //审批完剩下的人员数量
                if(people>list.size())  //如果剩下的人员要大于当前的，执行节点还是当前的节点
                {
                    next_node=node_id;
                }
                else
                {
                    //下一个节点
                    changeUsersNode(wfNodeModelNext,wf_id,taskId,oper);
                }
            }
            //执行到下一个节点
            sql="update jw_wf_task set update_by=?,update_time=?,node_id=? where id=?" ;
            args = new Object[]{oper, DateUtils.getNowDate(),next_node,taskId};
            JwDbHelper.update(sql,args);
        }
        else if(shape.equals("start-node"))         //开始节点
        {

        }
        //执行节点的流程详情
        String node_name=wfNodeModelNext.getName();
        if(StringUtils.isEmpty(desc))
        {
            desc=node_name;
        }
        //处理当前节点的审批信息
        WfNodeModel wfNodeModel=flowService.getPrevNode(wf_id,node_id);
        String pre_node_id=wfNodeModel.getId();
        String pre_desc=wfNodeModel.getName();
        processService.saveProcess(wf_id,taskId,pre_node_id,pre_desc,oper);

        //如果下一步就是结束了，直接执行结束操作
        //wfNodeModelNext=flowService.getNextNode(wf_id,node_id);
        //注释掉，是因为本身节点就是下一步节点
        shape=wfNodeModelNext.getShape();
        next_node=wfNodeModelNext.getId();
        if(shape.equals("end-node"))       //结束节点
        {
            //任务结束
            sql="update jw_wf_task set update_by=?,update_time=?,node_id=?,status='2' where id=?" ;
            args = new Object[]{oper, DateUtils.getNowDate(),next_node,taskId};
            if(JwDbHelper.update(sql,args)>0)
            {
                //所有审批人员清理
                taskHandlerService.removeAllUser(wf_id,taskId);
            }
            //执行结束节点的历史
            node_name=wfNodeModelNext.getName();
            if(StringUtils.isEmpty(desc))
            {
                desc=node_name;
            }
            processService.saveProcess(wf_id,taskId,node_id,desc,oper);
        }

        sql="select * from jw_wf_task where id=?";
        args = new Object[]{taskId};
        wfTaskModel = JwDbHelper.queryFirst(WfTaskModel.class,sql,args);
        return wfTaskModel;
    }

    @Override
    public WfTaskModel cancelTask(String taskId, String oper, String desc) {
        String sql="select * from jw_wf_task where id=?";
        Object[] args = new Object[]{taskId};
        WfTaskModel wfTaskModel = JwDbHelper.queryFirst(WfTaskModel.class,sql,args);
        //String now_node_id=wfTaskModel.getNode_id();    //当前需要执行的节点
        String wf_id=wfTaskModel.getWf_id();    //当前流程ID
        String node_id=wfTaskModel.getNode_id();
        processService.saveProcess(wf_id,taskId,node_id,desc,oper);
        //任务结束
        sql="update jw_wf_task set update_by=?,update_time=?,status='3' where id=?" ;
        args = new Object[]{oper, DateUtils.getNowDate(),taskId};
        if(JwDbHelper.update(sql,args)>0)
        {
            //所有审批人员清理
            taskHandlerService.removeAllUser(wf_id,taskId);
        }
        return null;
    }

    //撤回
    @Override
    public WfTaskModel retractTask(String taskId, String oper) {
        //查询当前任务、当前人的流程信息，如果存在执行查找流程审批历史的上一步操作
        String sql="select * from jw_wf_task where id=? and update_by=?";
        Object[] args = new Object[]{taskId,oper};
        WfTaskModel wfTaskModel = JwDbHelper.queryFirst(WfTaskModel.class,sql,args);
        if(wfTaskModel!=null)
        {
            String node_id=wfTaskModel.getNode_id();
            //WfNodeModel nodePre=flowService.getPrevNode(taskId,node_id);
            //String pre_node_id=nodePre.getId();

            //当前人的审批上一步操作。
            sql="select * from jw_wf_process where task_id=? and create_by=? oreder by create_time desc";
            args = new Object[]{taskId,oper};
            List<WfProcessModel> plist=JwDbHelper.queryList(WfProcessModel.class,sql,args);
            if(plist.size()>0)
            {
                WfProcessModel wfProcessModel=plist.get(0);
                String pre_node_id=wfProcessModel.getNode_id();
                String wf_id=wfProcessModel.getWf_id();
                //任务结束
                sql="update jw_wf_task set update_by=?,update_time=?,node_id=? where id=?" ;
                args = new Object[]{oper, DateUtils.getNowDate(),pre_node_id,taskId};
                if(JwDbHelper.update(sql,args)>0)
                {
                    //添加当前人员
                    taskHandlerService.addUser(wf_id,taskId,oper);
                }
                processService.saveProcess(wf_id,taskId,node_id,"(撤回) ",oper);
            }

            sql="select * from jw_wf_task where id=?";
            args = new Object[]{taskId};
            wfTaskModel = JwDbHelper.queryFirst(WfTaskModel.class,sql,args);
            return wfTaskModel;
        }
        return null;
    }
    //发回到开始
    @Override
    public WfTaskModel returnTask(String taskId, String oper,String desc) {
        String sql="select * from jw_wf_task where id=? ";
        Object[] args = new Object[]{taskId};
        WfTaskModel wfTaskModel = JwDbHelper.queryFirst(WfTaskModel.class,sql,args);
        String create_by=wfTaskModel.getCreate_by();    //开始人
        String wf_id=wfTaskModel.getWf_id();        //流程ID

        /*sql="select * from jw_wf_code where id=? ";
        args = new Object[]{wf_id};
        WfCodeModel wfCodeModel= JwDbHelper.queryFirst(WfCodeModel.class,sql,args);*/

        WfNodeModel fisrtNode=flowService.getFirstNode(wf_id);  //起始节点
        String firstNID=fisrtNode.getId();
        //任务发回开始
        sql="update jw_wf_task set update_by=?,update_time=?,node_id=? where id=?" ;
        args = new Object[]{oper, DateUtils.getNowDate(),firstNID,taskId};
        if(JwDbHelper.update(sql,args)>0)
        {
            processService.saveProcess(wf_id,taskId,firstNID,desc+"(发回)",oper);
        }

        sql="select * from jw_wf_task where id=? ";
        args = new Object[]{taskId};
        wfTaskModel = JwDbHelper.queryFirst(WfTaskModel.class,sql,args);
        return wfTaskModel;
    }
    //跳转节点，也可以用于发回任意节点
    @Override
    public WfTaskModel executeAndJumpTask(String taskId, String nodeId, String oper,String desc) {
        String sql="select * from jw_wf_task where id=? ";
        Object[] args = new Object[]{taskId};
        WfTaskModel wfTaskModel = JwDbHelper.queryFirst(WfTaskModel.class,sql,args);
        String node_id=wfTaskModel.getNode_id();    //当前节点
        String wf_id=wfTaskModel.getWf_id();        //流程ID

        sql="update jw_wf_task set update_by=?,update_time=?,node_id=? where id=?" ;
        args = new Object[]{oper, DateUtils.getNowDate(),nodeId,taskId};
        if(JwDbHelper.update(sql,args)>0)
        {
            processService.saveProcess(wf_id,taskId,node_id,desc+"(跳转)",oper);
            //将跳转到得节点下的所有人员信息添加到处理中

        }

        return null;
    }

    @Override
    public WfTaskModel deleteTask(String taskId, String oper) {
        Object[] args = new Object[]{taskId};
        String sql="select from jw_wf_task where id=?";
        WfTaskModel wfTaskModel=JwDbHelper.queryFirst(WfTaskModel.class,sql,args);

        sql="delete from jw_wf_process where task_id=?";
        JwDbHelper.update(sql,args);

        sql="delete from jw_wf_task_handler where task_id=?";
        JwDbHelper.update(sql,args);

        sql="delete from jw_wf_task where id=?";
        JwDbHelper.update(sql,args);

        return wfTaskModel;
    }

    @Override
    public WfTaskModel startFreeTask(String taskId, String wfId, String oper) {
        return null;
    }

    @Override
    public WfTaskModel executeFreeTask(String taskId, String oper) {
        return null;
    }


    /**
     * 根据下一个节点重新处理变换审批人员范围
     * @param node 节点，查找人员组
     * @param wf_id 流程ID
     * @param taskId    流程任务ID
     * @param oper  单签人员
     */
    public void changeUsersNode(WfNodeModel node,String wf_id,String taskId,String oper)
    {
        taskHandlerService.removeAllUser(wf_id,taskId);     //删除所有的审批人员
        //重新填充下一个节点的审批人员
        List<UserModel> userlist=nodeService.getUserByGroup(node);
        List<String> users=new ArrayList<>();
        if(userlist==null||userlist.size()<=0)
        {
            users=new ArrayList<>();
            users.add(oper);
        }
        else
        {
            for (UserModel user:userlist) {
                users.add(user.getValue());
            }
        }
        taskHandlerService.addUser(wf_id,taskId,users.toArray(new String[users.size()]));
    }

    @Override
    public List<WfProcessModel> getTaskHisList(String taskid)
    {
        return processService.getList(taskid);
    }
}
